| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- import { IS_PLATFORM, LOCAL_STORAGE_KEYS, useParams } from 'common'
- import { AlertTriangleIcon } from 'lucide-react'
- import { NextPage } from 'next'
- import { useRouter } from 'next/router'
- import { useEffect, useState } from 'react'
- import {
- Alert,
- AlertDescription,
- AlertTitle,
- Select,
- SelectContent,
- SelectItem,
- SelectTrigger,
- SelectValue,
- } from 'ui'
- import { ShimmeringLoader } from 'ui-patterns'
- import {
- Header,
- LoadingCardView,
- NoOrganizationsState,
- } from '@/components/interfaces/Home/ProjectList/EmptyStates'
- import { ProjectList } from '@/components/interfaces/Home/ProjectList/ProjectList'
- import { HomePageActions } from '@/components/interfaces/HomePageActions'
- import { PageLayout } from '@/components/layouts/PageLayout/PageLayout'
- import { ScaffoldContainer, ScaffoldSection } from '@/components/layouts/Scaffold'
- import { useOrganizationsQuery } from '@/data/organizations/organizations-query'
- import { useLocalStorageQuery } from '@/hooks/misc/useLocalStorage'
- import { withAuth } from '@/hooks/misc/withAuth'
- // [Joshen] I'd say we don't do route validation here, this page will act more
- // like a proxy to the project specific pages, and we let those pages handle
- // any route validation logic instead
- const GenericProjectPage: NextPage = () => {
- const router = useRouter()
- const { slug } = useParams()
- const { routeSlug, ...queryParams } = router.query
- const [lastVisitedOrgSlug] = useLocalStorageQuery(
- LOCAL_STORAGE_KEYS.LAST_VISITED_ORGANIZATION,
- ''
- )
- const {
- data: organizations = [],
- isSuccess: isSuccessOrganizations,
- isPending: isLoadingOrganizations,
- isError: isErrorOrganizations,
- } = useOrganizationsQuery({
- enabled: IS_PLATFORM,
- })
- const [selectedSlug, setSlug] = useState<string>(
- slug || lastVisitedOrgSlug || organizations[0]?.slug
- )
- const selectedOrganization = organizations.find((x) => x.slug === selectedSlug)
- const query = Object.keys(queryParams).length
- ? `?${new URLSearchParams(queryParams as Record<string, string>)}`
- : undefined
- const urlRewriterFactory = (slug: string | string[] | undefined) => {
- return (projectRef: string) => {
- const hash = location.hash
- if (!Array.isArray(slug)) {
- return [`/project/${projectRef}`, query, hash].filter(Boolean).join('')
- }
- const slugPath = slug.join('/')
- return [`/project/${projectRef}/${slugPath}`, query, hash].filter(Boolean).join('')
- }
- }
- useEffect(() => {
- if (!!lastVisitedOrgSlug) {
- setSlug(lastVisitedOrgSlug)
- } else if (isSuccessOrganizations) {
- setSlug(organizations[0]?.slug)
- }
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [lastVisitedOrgSlug, isSuccessOrganizations])
- return (
- <div className="h-screen flex flex-col">
- <Header />
- <PageLayout className="grow min-h-0" title="Select a project to continue">
- <ScaffoldContainer className="grow flex flex-col gap-y-4">
- <ScaffoldSection isFullWidth className="py-0">
- <div className="flex items-center gap-x-2">
- {isLoadingOrganizations ? (
- <ShimmeringLoader className="w-60 py-0 h-[26px]" />
- ) : (
- <Select value={selectedSlug} onValueChange={setSlug}>
- <SelectTrigger size="tiny" className="w-60 truncate">
- <div className="flex items-center gap-x-2">
- <p className="text-xs text-foreground-light">Organization:</p>
- <SelectValue placeholder="Select an organization" />
- </div>
- </SelectTrigger>
- <SelectContent className="col-span-8">
- {organizations.map((org) => (
- <SelectItem key={org.slug} value={org.slug} className="text-xs">
- {org.name}
- </SelectItem>
- ))}
- </SelectContent>
- </Select>
- )}
- <HomePageActions hideNewProject />
- </div>
- </ScaffoldSection>
- <ScaffoldSection isFullWidth className="py-0">
- {isLoadingOrganizations ? (
- <LoadingCardView />
- ) : isErrorOrganizations ? (
- <Alert variant="warning">
- <AlertTriangleIcon />
- <AlertTitle>Failed to load your Briven organizations</AlertTitle>
- <AlertDescription>Try refreshing the page</AlertDescription>
- </Alert>
- ) : organizations.length === 0 ? (
- <NoOrganizationsState />
- ) : !!selectedOrganization ? (
- <ProjectList
- organization={selectedOrganization}
- rewriteHref={urlRewriterFactory(routeSlug)}
- />
- ) : null}
- </ScaffoldSection>
- </ScaffoldContainer>
- </PageLayout>
- </div>
- )
- }
- export default withAuth(GenericProjectPage)
|